package com.ithuameng.cosy.coder.protobuf;

import com.ithuameng.cosy.constant.ChannelAttr;
import com.ithuameng.cosy.constant.DataType;
import com.ithuameng.cosy.exception.ReadInvalidTypeException;
import com.ithuameng.cosy.model.Pong;
import com.ithuameng.cosy.model.SentBody;
import com.ithuameng.cosy.model.proto.SentBodyProto;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * websocket协议 protobuf消息体解码
 *
 * @author ithuameng
 */
public class WebMessageDecoder extends MessageToMessageDecoder<BinaryWebSocketFrame> {

    @Override
    protected void decode(ChannelHandlerContext context, BinaryWebSocketFrame frame, List<Object> list) throws Exception {

        context.channel().attr(ChannelAttr.PING_COUNT).set(null);

        ByteBuf buffer = frame.content();

        byte type = buffer.readByte();

        if (DataType.PONG.getValue() == type) {
            list.add(Pong.getInstance());
            return;
        }

        if (DataType.SENT.getValue() == type) {
            list.add(getBody(buffer));
            return;
        }

        throw new ReadInvalidTypeException(type);
    }

    protected SentBody getBody(ByteBuf buffer) throws IOException {

        InputStream inputStream = new ByteBufInputStream(buffer);

        SentBodyProto.Model proto = SentBodyProto.Model.parseFrom(inputStream);

        SentBody body = new SentBody();
        body.setData(proto.getDataMap());
        body.setKey(proto.getKey());
        body.setTimestamp(proto.getTimestamp());

        return body;
    }
}
